﻿using StarPizza.ViewModel;
using StarPizza.View.ChefSystem;
using StarPizza.View.ClientSystem;
using StarPizza.View.ManagerSystem;
using StarPizza.View.User;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using StarPizza.View;

namespace StarPizza
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        #region ViewModels
        ConfigVM config;
        Shell shell;
        #endregion

        #region Views
        List<Window> windows;

        Config configWindow;

        LoginWindow loginWindow;

        RegistrationWindow registrationWindow;
        EditUserWindow editClientWindow;
        UserWindow clientWindow;

        ChefWindow chefWindow;

        ManagerWindow managerWindow;
        #endregion Views

        #region Creation and closing logic of Windows
        bool isClosing = false;
        private void OnClosing(object sender, System.ComponentModel.CancelEventArgs shouldCancelEventArgs)
        {
            if (isClosing)
                return;
            
            //At this point we can introduce later any check towards the Shell if we should cancel (e.g. unsaved changes)

            isClosing = true;
            var windowsToClose = windows
                .Where(window => window != (Window)sender)
                .ToList();
            windowsToClose
                .ForEach(window => window.Close());
        }
        //I am sorry about this:...
        private void CreateWindow<WindowType>(ref WindowType window) where WindowType : Window, new() 
        {
            window = new WindowType();
            windows.Add(window);
            window.Closing += this.OnClosing;
        }
        private void CloseWindowsInternally()
        {
            OnClosing(sender: null, shouldCancelEventArgs: null);
        }
        #endregion 

        private void CreateBusinessWindows()
        {
            CreateWindow(ref loginWindow);

            CreateWindow(ref registrationWindow);
            CreateWindow(ref editClientWindow);
            CreateWindow(ref clientWindow);

            CreateWindow(ref chefWindow);

            CreateWindow(ref managerWindow);
        }
        
        private void SetupBusinessContexts()
        {
            loginWindow.DataContext = shell.UserAuthenticator;

            registrationWindow.DataContext = shell.ClientRegistrator;
            editClientWindow.DataContext = shell.ClientDataEditor;
            clientWindow.DataContext = shell.ClientSystemVM;

            chefWindow.DataContext = shell.ChefSystemVM;

            managerWindow.DataContext = shell.ManagerSystemVM;
        }
       
        private void Application_Startup(object sender, StartupEventArgs e)
        {
            windows = new List<Window>();

            // Uncomment one of the following statements:
            ConfigureThenStart();        //Ask the user for connection string
            //Start(connectionString: "");   //Use the default connection string
        }
        private void ConfigureThenStart()
        {
            config = new ConfigVM();
            config.ConfigDone += Start;
            CreateWindow(ref configWindow);
            configWindow.DataContext = config;
            config.IsVisible = true;
        }
        void Start(string connectionString)
        {
            shell = new Shell(connectionString);
            CreateBusinessWindows();
            SetupBusinessContexts();
            shell.Start();

            // Uncomment one of the following for testing purposes:
            //LoginChef();
            //LoginManager();
            //LoginClient();
        }
    }
}
